package icasue.reflect.handles.integer;

import icasue.reflect.handles.HandleSupplier;
import icasue.reflect.handles.OFAble;
import icasue.reflect.handles.object.ObjectOF;
import icasue.reflect.exceptions.HandleException;
import icasue.reflect.handles.classes.ClassOF;
import icasue.reflect.handles.exception.ExceptionOF;

import java.util.function.Function;

/**
 * @Author: Qiao Hang
 * @CreateDate: 2020/12/2 上午11:15
 * @UpdateDate:
 * @Description:
 */
public class IntegerOF implements OFAble {


    /**
     * compare_ (integer,integer)  doc: eq -> 0; left > right -> 1; left < right -> -1;
     * max_ (integer,integer)  doc: return which value is bigger.
     * min_ (integer,integer)  doc: return which value is smaller.
     * valueOf_ (string)  doc: format str value to int.
     *
     * All method check pass.
     */

    /**
     * eq -> 0
     * left > right -> 1
     * left < right -> -1
     */
    public static HandleSupplier.FunctionAry<Object> compare_ = (leftRight) -> {
        try {
            if(leftRight.length != 2)
                throw ExceptionOF.handleExcInvocation_.apply("IntegerOF.compare_ : required 2 params");
            if(ObjectOF.isNull_.test(leftRight[0]) || ObjectOF.isNull_.test(leftRight[1]))
                throw ExceptionOF.handleExcInvocation_.apply("IntegerOF.compare_ : left and right value must not be null.");
            if(ClassOF.isAssignableFrom_.test(new Object[]{Integer.class,leftRight[0].getClass()})
                    && ClassOF.isAssignableFrom_.test(new Object[]{Integer.class,leftRight[1].getClass()}))
                return IntegerO.compare.invoke(leftRight[0],leftRight[1]);
            throw ExceptionOF.handleExcInvocation_.apply("IntegerOF.compare_ : left and right value must assignable from java.lang.Integer.");
        } catch (HandleException deepError){
            throw deepError;
        } catch (Throwable throwable) {
            throw ExceptionOF.handleExcInvocation_.apply("IntegerOF.compare_ : occur an error : " , throwable.getMessage());
        }
    };

    /**
     * return which bigger.
     */
    public static HandleSupplier.FunctionAry<Object> max_ = (leftRight) -> {
        try {
            if(leftRight.length != 2)
                throw ExceptionOF.handleExcInvocation_.apply("IntegerOF.max_ : required 2 params");
            if(ObjectOF.isNull_.test(leftRight[0]) || ObjectOF.isNull_.test(leftRight[1]))
                throw ExceptionOF.handleExcInvocation_.apply("IntegerOF.max_ : left and right value must not be null.");
            if(ClassOF.isAssignableFrom_.test(new Object[]{Integer.class,leftRight[0].getClass()})
                    && ClassOF.isAssignableFrom_.test(new Object[]{Integer.class,leftRight[1].getClass()}))
                return IntegerO.max.invoke(leftRight[0],leftRight[1]);
            throw ExceptionOF.handleExcInvocation_.apply("IntegerOF.max_ : left and right value must assignable from java.lang.Integer.");
        } catch (HandleException deepError){
            throw deepError;
        } catch (Throwable throwable) {
            throw ExceptionOF.handleExcInvocation_.apply("IntegerOF.max_ : occur an error : " , throwable.getMessage());
        }
    };

    /**
     * return which smaller.
     */
    public static HandleSupplier.FunctionAry<Object> min_ = (leftRight) -> {
        try {
            if(leftRight.length != 2)
                throw ExceptionOF.handleExcInvocation_.apply("IntegerOF.min_ : required 2 params");
            if(ObjectOF.isNull_.test(leftRight[0]) || ObjectOF.isNull_.test(leftRight[1]))
                throw ExceptionOF.handleExcInvocation_.apply("IntegerOF.min_ : left and right value must not be null.");
            if(ClassOF.isAssignableFrom_.test(new Object[]{Integer.class,leftRight[0].getClass()})
                    && ClassOF.isAssignableFrom_.test(new Object[]{Integer.class,leftRight[1].getClass()}))
                return IntegerO.min.invoke(leftRight[0],leftRight[1]);
            throw ExceptionOF.handleExcInvocation_.apply("IntegerOF.min_ : left and right value must assignable from java.lang.Integer.");
        } catch (HandleException deepError){
            throw deepError;
        } catch (Throwable throwable) {
            throw ExceptionOF.handleExcInvocation_.apply("IntegerOF.min_ : occur an error : " , throwable.getMessage());
        }
    };

    /**
     * accept string, return object, actually is integer.
     */
    public static Function<Object, Object> valueOf_ = (strNum) -> {
        try {
            if(ObjectOF.isNull_.test(strNum))
                throw ExceptionOF.handleExcInvocation_.apply("IntegerOF.valueOf_ : param must not be null.");
            if(!ObjectOF.equals_.test(new Object[]{String.class,strNum.getClass()}))
                throw ExceptionOF.handleExcInvocation_.apply("IntegerOF.valueOf_ : param must be java.lang.String.");
            return IntegerO.valueOf.invoke(strNum);
        } catch (HandleException deepError){
            throw deepError;
        } catch (Throwable throwable) {
            throw ExceptionOF.handleExcInvocation_.apply("IntegerOF.valueOf_ : occur an error : " , throwable.getMessage());
        }
    };

}
